package cn.demomaster.quickrouter.actionbar;

import static androidx.constraintlayout.widget.Constraints.TAG;
import static com.demomaster.quickcompat.view.loading.modle.LoadStateType.COMPLETE;
import static com.demomaster.quickcompat.view.loading.modle.LoadStateType.ERROR;
import static com.demomaster.quickcompat.view.loading.modle.LoadStateType.LOADING;

import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.demomaster.quickcompat.view.StateView;
import com.demomaster.quickcompat.view.loading.modle.LoadStateType;
import com.demomaster.quickcompat.widget.ImageTextView;
import com.demomaster.quickcompat.util.QuickThread;
import cn.demomaster.quickrouter.R;

/**
 * Created by Squirrel桓 on 2018/12/25.
 */
public class ActionBarTipLayout extends FrameLayout {
    public ActionBarTipLayout(@NonNull Context context) {
        super(context);
        init();
    }

    public ActionBarTipLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ActionBarTipLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private View contentView;

    public View getContentView() {
        return contentView;
    }

    public void setContentView(View contentView) {
        this.contentView = contentView;
        this.addView(contentView);
    }

    private StateView stateView;
    private TextView textView;
    private ImageTextView itv_retry;
    int contentViewResID;
    private ActionBarState.OnLoadingStateListener loadingStateListener;
    private ActionBarState.Loading retry;

    public void setLoadingStateListener(ActionBarState.OnLoadingStateListener onLoadingStateListener) {
        if (onLoadingStateListener == null) {
            return;
        } else {
            onLoadingStateListener.setResult(retry);
        }
        this.loadingStateListener = onLoadingStateListener;
        actionBarState.setOnLoadingStateListener(onLoadingStateListener);
    }

    public void setContentView(int contentViewResID) {
        this.contentViewResID = contentViewResID;
        LayoutInflater mInflater = LayoutInflater.from(getContext());
        mInflater.inflate(contentViewResID, this);
        this.contentView = this.getChildAt(0);
        this.stateView = contentView.findViewById(R.id.sv_icon);
        this.textView = contentView.findViewById(R.id.textView);
        this.itv_retry = contentView.findViewById(R.id.itv_retry);
        this.itv_retry.setTextSize(14);
        this.itv_retry.setText(getResources().getString(com.demomaster.quickcompat.R.string.retry));
        itv_retry.setOnClickListener(view -> {
            if (actionBarState != null && actionBarState.getOnLoadingStateListener() != null) {
                loading();
                //新线程处理耗时操作
                QuickThread.runOnSubThread(() -> {
                    try {
                        actionBarState.getOnLoadingStateListener().loading();
                    } catch (Exception e) {
                        Log.i(TAG,e.toString());
                    }
                });
            }
        });
    }

    private ActionBarState actionBarState;
    public void setActionBarState(ActionBarState actionBarState) {
        this.actionBarState = actionBarState;
    }

    private LayoutParams layoutParams_tip;
    public void init() {
        retry = new ActionBarState.Loading() {
            @Override
            public void hide() {
                QuickThread.runOnUiThread(() -> {
                    //成功 结束并隐藏
                    ActionBarTipLayout.this.hide();
                });
            }

            @Override
            public void success() {
                QuickThread.runOnUiThread(() -> {
                    //成功 结束并隐藏
                    ActionBarTipLayout.this.completeAndHide();
                });
            }

            @Override
            public void fail() {
                QuickThread.runOnUiThread(() -> {
                    //失败 改变状态不隐藏
                    ActionBarTipLayout.this.errorAndShow();
                });
            }

            @Override
            public void success(final String message) {
                QuickThread.runOnUiThread(() -> {
                    //成功 结束并隐藏
                    ActionBarTipLayout.this.completeAndHide();
                    textView.setText(message);
                });
            }

            @Override
            public void fail(final String message) {
                QuickThread.runOnUiThread(() -> {
                    //失败 改变状态不隐藏
                    ActionBarTipLayout.this.errorAndShow();
                    textView.setText(message);
                });
            }

            @Override
            public void setText(final String message) {
                ((Activity) getContext()).runOnUiThread(() -> textView.setText(message));
            }
        };
        actionBarState = new ActionBarState();

        if (getLayoutParams() == null) {
            layoutParams_tip = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            setLayoutParams(layoutParams_tip);
        }
        this.setOnClickListener(view -> {
            //hide();
        });

        this.setOnTouchListener((view, motionEvent) -> {
            switch (motionEvent.getAction()) {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_CANCEL:
                    position_Y = motionEvent.getY();
                    break;
                case MotionEvent.ACTION_UP:
                    position_Y = topMin + motionEvent.getY();
                    if (stateType == ERROR || stateType == LOADING) {
                        show();
                    } else {
                        hide();
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    float distanc_y = motionEvent.getY() - position_Y;
                    layoutParams_tip = (LayoutParams) getLayoutParams();
                    int top_c = (int) (layoutParams_tip.topMargin + distanc_y);
                    if (top_c > topMin && top_c < topMax) {
                        layoutParams_tip.topMargin = top_c;
                    }
                    Log.i(TAG,"topMax=" + topMax + ",topMin=" + topMin);
                    setLayoutParams(layoutParams_tip);
                    break;
            }
            return false;
        });

        setVisibility(INVISIBLE);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        //setActionBarHeight(bottom - top);
        /*
        QdLog.i( "onLayout max="+max+",height=" +(bottom-top)+","+ (-max+top)+",top="+top+", getHeight()=" +  getHeight());*/
    }

    private int topMax;
    private int topMin;
    private float position_Y;
    private final int duration = 400;
    ValueAnimator animator;
    public void startAnimation() {
        setVisibility(View.VISIBLE);
        animator = ValueAnimator.ofFloat(topMin, topMax);
        animator.setDuration(duration);
        animator.addUpdateListener(animation -> {
            float value = (float) animation.getAnimatedValue();
            layoutParams_tip.topMargin = (int) value;
            setLayoutParams(layoutParams_tip);
            if (value == topMin) {
                setVisibility(GONE);
            } else {
                setVisibility(VISIBLE);
            }
        });
        //animator.setRepeatMode(ValueAnimator.REVERSE);
        //animator.setRepeatCount(ValueAnimator.INFINITE);//accelerate_decelerate_interpolator
        animator.setInterpolator(new AccelerateDecelerateInterpolator());
        animator.start();
    }

    public void show() {
        layoutParams_tip = (LayoutParams) getLayoutParams();
        if (animator != null) {
            animator.setFloatValues(layoutParams_tip.topMargin, getHeight() + topMin);
            animator.setDuration((int) (duration * ((float) ((getHeight() + topMin) - layoutParams_tip.topMargin) / getHeight())));
            animator.start();
        }
    }

    public void hide() {
        layoutParams_tip = (LayoutParams) getLayoutParams();
        if (animator != null) {
            animator.setFloatValues(topMin, layoutParams_tip.topMargin);
            animator.setDuration((int) (duration * ((float) (layoutParams_tip.topMargin - topMin) / getHeight())));
            animator.reverse();
        }
    }

    //成功 结束并隐藏
    public void completeAndHide() {
        stateType = COMPLETE;
        stateView.setStateType(COMPLETE);
        itv_retry.setVisibility(GONE);
        hideDelayed(3000);
    }

    //失败 改变状态不隐藏
    public void errorAndShow() {
        stateType = ERROR;
        stateView.setStateType(ERROR);
    }

    public void loading() {
        stateType = LOADING;
        stateView.setStateType(stateType);
        itv_retry.setVisibility(GONE);
    }

    private int actionBarHeight;
    public void setActionBarHeight(int height) {
        this.actionBarHeight = height;
        topMin = actionBarHeight - getMeasuredHeight();
        topMax = actionBarHeight;
        Log.i(TAG,"setActionBarHeight=" + height + ", getHeight()=" + getHeight() + ",topMin=" + topMin + ",topMax=" + topMax);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        topMin = actionBarHeight - getMeasuredHeight();
        topMax = actionBarHeight;
    }

    /**
     * 状态
     * 1.可以手动点击关闭
     * 2.可以强制固定不可关闭
     * 3.定时关闭
     * 4.收到更新消息
     */
    Handler handler = new Handler();
    private final Runnable myRunnable = new Runnable() {
        @Override
        public void run() {
            if (stateType == ERROR || stateType == LOADING) {

            } else {
                hide();
            }
        }
    };

    public void onDestroy() {
        handler.removeCallbacks(myRunnable);
    }

    public void showDelayed() {
        showDelayed(5000);
    }

    private int delayedTime = 5000;

    public void showDelayed(int time) {
        delayedTime = time;
        startAnimation();
        handler.removeCallbacks(myRunnable);
        handler.postDelayed(myRunnable, delayedTime);
    }

    public void hideDelayed() {
        hideDelayed(5000);
    }

    public void hideDelayed(int time) {
        delayedTime = time;
        handler.removeCallbacks(myRunnable);
        handler.postDelayed(myRunnable, delayedTime);
    }

    private LoadStateType stateType = COMPLETE;

    public void showWarning(String message) {
        stateType = LoadStateType.WARNING;
        stateView.setStateType(stateType);
        textView.setText(message);
        itv_retry.setVisibility(GONE);
        showDelayed();
    }

    public void showComplete(String message) {
        stateType = COMPLETE;
        stateView.setStateType(stateType);
        textView.setText(message);
        itv_retry.setVisibility(GONE);
        showDelayed();
    }

    public void showError(String message) {
        stateType = ERROR;
        this.stateView = contentView.findViewById(R.id.sv_icon);
        if (stateView != null) {
            stateView.setStateType(stateType);
        }
        textView.setText(message);
        itv_retry.setVisibility(VISIBLE);
        showDelayed();
    }

    public void showLoading(String message) {
        stateType = LOADING;
        stateView.setStateType(stateType);
        textView.setText(message);
        itv_retry.setVisibility(GONE);
        showDelayed();
    }

    public ACTIONBARTIP_TYPE mActionbartip_type = ACTIONBARTIP_TYPE.NORMAL;

    public void setActionTipType(ACTIONBARTIP_TYPE actionbartip_type) {
        mActionbartip_type = actionbartip_type;
    }

    @Override
    public void setLayoutParams(ViewGroup.LayoutParams params) {
        super.setLayoutParams(params);

        LayoutParams layoutParams = (LayoutParams) getLayoutParams();
        Rect rect = new Rect(0, -layoutParams.topMargin + topMax, getWidth(), getHeight());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            setClipBounds(rect);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (animator != null) {
            animator.cancel();
        }
        actionBarState = null;
        retry = null;
    }
}
